<template>
  <v-container style="display: flex; height: calc(100vh - 64px); flex-direction: column" fluid>
    <practice-frame ref="practiceFrame" practice-model="listen" :setPracticeCallback="setPracticeCallback"
      :tryPlayWordSymbolVoice="play" :clearPracticeConfigCallback="getPracticeConfit"
      :quickKeyListener="quickKeyListener" :VKeyboardInputListener="VKeyboardInputListener"
      :VKeyboardPressListener="VKeyboardPressListener" :sensorListener="sensorListener"
      :autoPalyOnceListener="autoPalyOnceListener">
      <template v-slot:center>
        <div class="centerDiv">
          <div>
            <div :class="{ div_blur: coverConfig.word }" style="font-size: 30px"
              @click="coverConfig.word = !coverConfig.word">{{ currentWord.word }}</div>
            <span :class="{ div_blur: coverConfig.word }" @click="coverConfig.word = !coverConfig.word">
              <strong v-if="currentWord.region != null">{{
                currentWord.region
              }}</strong>
              <strong>[ {{ currentWord.symbol }} ]</strong>
            </span>
            <!-- <br />
            <strong v-if="currentWord.meanSelf != null">{{
              currentWord.meanSelf.type
            }}</strong> -->
            <p :class="{ div_blur: coverConfig.explain, 'text-limit': true }" style="margin: 20px auto"
              @click="coverConfig.explain = !coverConfig.explain">
              <strong v-if="currentWord.meanSelf != null && !config.titleLocalSwitch">
                {{ currentWord.meanSelf.type }}
              </strong>
              <strong v-if="currentWord.meanLocalType != null && config.titleLocalSwitch">
                {{ currentWord.meanLocalTypee }}
              </strong>
              {{ !config.titleLocalSwitch ?'':currentWord.meanLocalType+'.' }}
              {{ !config.titleLocalSwitch ? currentWord.explain : currentWord.meanLocalExplain }}
            </p>
          </div>
          <v-icon @click="refreshCurrent" icon="mdi-wrap" />
          <v-text-field id="replyWordSwitch" v-if="config.replyWordSwitch" :style="{ 'color': replyOneColor }"
            @keyup.enter="reply" append-inner-icon="mdi-send" @click:append-inner="reply" v-model.trim="myAnswer"
            label="请回答听到的单词" ref="wordField" autocomplete="off" v-show="!config.showKeyboard" />
          <div v-if="config.showKeyboard">
            <p v-if="myAnswer != null && myAnswer != ''" :style="{ 'color': replyOneColor,'position':'relative' }" class="flat-input">
              <v-icon color="error" size="x-small" style="right: 10px;top:12px;position: absolute;" icon="mdi-close-circle-outline"
                @click="cancelVKBoardInput"></v-icon>
              <span style="color:#2196F3">{{ myAnswer }}</span>
            </p>
            <p v-else :style="{ 'color': 'gray', 'font-size': '18px' }" class="flat-input">
              请作答
            </p>
          </div>
          <div v-if="config.replyMeanSwitch">
            <v-text-field id="replyMeanSwitch" :style="{ 'color': replyTwoColor }" @keyup.enter="reply"
              append-inner-icon="mdi-send" @click:append-inner="reply" v-model.trim="myAnswerOfMean" label="请回答单词意思"
              ref="meanField">
              <!-- <template v-slot:prepend>
                <v-select
                  style="width: 100px"
                  :items="wordTypeItems"
                  v-model="selectedWordTypeItem"
                  label="词性"
                ></v-select>
              </template> -->
            </v-text-field>
          </div>
          <div style="margin-top: 20px">
            <v-btn @click="play" v-if="!voiceLoading" class="ma-2" :color="!playing ? 'indigo-lighten-3' : 'indigo'"
              :icon="!playing ? 'mdi-volume-off' : 'mdi-volume-high'" />
            <v-progress-circular v-if="voiceLoading" indeterminate color="primary" />
          </div>
        </div>
      </template>
    </practice-frame>
  </v-container>
</template>

<script>
import { listeningAndWriting } from "@/api/practice.js";
import { queryUserPracticeConfig } from "@/api/practice.js";
import { ttsVoice } from "@/api/voice.js";
export default {
  components: {},
  data() {
    return {
      wordTypeItems: [
        "n",
        "vt",
        "vi",
        "adj",
        "adv",
        "pron",
        "prep",
        "v",
        "aux",
        "num",
      ],
      selectedWordTypeItem: null,
      config: {},
      currentWord: { word: "", meanSelf: "", explain: "", wordId: 0 },
      myAnswer: null,
      myAnswerOfMean: null,
      voiceLoading: true,
      blur: true,
      wordTemp: undefined,
      mute: false,
      voiceInit: 0,
      playing: false,
      audio: null,
      retry: false,
      coverConfig: { word: true, explain: true },
      replyOneColor: 'initial',
      replyTwoColor: 'initial',
      keyboard: null,
    };
  },
  created() {
    this.loadingListeningAndWritingCache();
    this.getPracticeConfit();
  },
  methods: {
    loadingListeningAndWritingCache() {
      this.overlay = true;
      listeningAndWriting({ bookId: this.$route.params.bookId })
        .then(() => {
          // this.nextRaw()
          this.$refs.practiceFrame.nextRaw();
        })
        .finally(() => (this.overlay = false));
    },
    reply() {
      if (this.config.replyWordSwitch && this.config.replyMeanSwitch) {
        let replyOne = this.replyOfWord()
        let replyTwo = this.replyOfLocalMean()
        if (replyOne.right && replyTwo.right) {
          this.sendOutcome({ right: true, wordId: this.currentWord.wordId, retry: replyOne.retry && replyTwo.retry })
        } else this.sendOutcome({ right: false, wordId: this.currentWord.wordId, retry: true })
        if (!replyOne.right) this.replyOneColor = 'red'; else this.replyOneColor = 'initial'
        if (!replyTwo.right) this.replyTwoColor = 'red'; else this.replyTwoColor = 'initial'
      } else if (this.config.replyWordSwitch) {
        this.sendOutcome(this.replyOfWord())
      } else if (this.config.replyMeanSwitch) {
        this.sendOutcome(this.replyOfLocalMean())
      }
    },
    replyOfWord() {
      if (this.myAnswer != this.currentWord.word) {
        this.retry = true;
      }
      return {
        right: this.myAnswer == this.currentWord.word,
        wordId: this.currentWord.wordId,
        retry: this.retry,
      }
      // this.$refs.practiceFrame.reply({
      //   right: this.myAnswer == this.currentWord.word,
      //   wordId: this.currentWord.wordId,
      //   retry: this.retry,
      // });
    },
    replyOfLocalMean() {
      // console.log("this.currentWord = ", this.currentWord);
      // console.log("selectedWordTypeItem = ", this.selectedWordTypeItem);
      if (this.currentWord.meanLocal == null || this.currentWord.meanLocal.length == 0) {
        this.retry = true;
        return { right: false, wordId: this.currentWord.wordId, retry: this.retry };
      }
      // if(this.myAnswerOfMean.search('（'))this.myAnswerOfMean=this.myAnswerOfMean.replaceAll('（','(')
      // if(this.myAnswerOfMean.search('）'))this.myAnswerOfMean=this.myAnswerOfMean.replaceAll('）',')')
      let verification = false;
      for (let i = 0; i < this.currentWord.meanLocal.length; i++) {
        if (verification) break
        let meanLocalItem = this.currentWord.meanLocal[i];
        // let wordType = meanLocalItem.type;
        if (meanLocalItem.mean.replaceAll('；', ';').search(";") != -1) {
          let meanSplit = meanLocalItem.mean.replaceAll('；', ';').split(";");
          for (let j = 0; j < meanSplit.length; j++) {
            // console.log(j, meanSplit[j]);
            let answerItem = meanSplit[j]
            let answerItemWithBracket = ''
            if (answerItem.search('（') != -1) answerItem = answerItem.replace(/\（.*?\）/g, '')
            if (answerItem.search(/\(/) != -1) {
              answerItem = answerItem.replace(/\(.*?\)/g, '')
              answerItemWithBracket = meanSplit[j].replace('(', '（').replace(')', '）')
            }
            if (this.myAnswerOfMean == answerItem || this.myAnswerOfMean == answerItemWithBracket || this.myAnswerOfMean == meanSplit[j]) {
              verification = true;
              // console.log("回答正确");
              break;
            }
          }
        } else {
          let answerItem = meanLocalItem.mean
          let answerItemWithBracket = ''
          if (answerItem.search('（') != -1) answerItem = answerItem.replace(/\（.*?\）/g, '')
          if (answerItem.search(/\(/) != -1) {
            answerItem = answerItem.replace(/\(.*?\)/g, '')
            answerItemWithBracket = meanLocalItem.mean.replace('(', '（').replace(')', '）')
          }
          if (this.myAnswerOfMean == answerItem || this.myAnswerOfMean == answerItemWithBracket || this.myAnswerOfMean == meanLocalItem.mean) {
            verification = true;
            // console.log("回答正确");
            break;
          }
        }
      }
      if (!verification) this.retry = true;
      return {
        right: verification,
        wordId: this.currentWord.wordId,
        retry: this.retry,
      }
      // this.$refs.practiceFrame.reply({
      //   right: verification,
      //   wordId: this.currentWord.wordId,
      //   retry: this.retry,
      // });
    },
    sendOutcome(outcome) {
      this.$refs.practiceFrame.reply(outcome)
      // this.$refs.practiceFrame.reply({
      //   right: verification,
      //   wordId: this.currentWord.wordId,
      //   retry: this.retry,
      // });
    },
    refreshCurrent() {
      if (this.wordTemp == undefined) return;
      this.trans(this.wordTemp);
    },
    play() {
      if (this.playing) {
        this.playing = false;
        this.audio.pause();
        this.audio = null;
        return;
      }
      this.audio = null;
      this.audio = new Audio(this.currentWord.symbolResource);
      this.audio.play();
      this.playing = true;
      this.audio.onended = () => {
        this.playing = false;
        if (this.currentWord.explainResource == null) return;
        this.audio = new Audio(this.currentWord.explainResource);
        this.audio.play();
        this.playing = true;
        this.audio.onended = () => {
          this.playing = false;
        };
      };
    },
    trans(nextWord) {
      // clearTimeout(this.getVoiceTimeout)
      if (nextWord == null) return;
      this.currentWord = {};
      this.currentWord.word = nextWord.word;
      if (nextWord.originalMeanings == null || nextWord.originalMeanings.length == 0) return;
      else if (nextWord.originalMeanings.length == 1) {
        this.currentWord.meanSelf = nextWord.originalMeanings[0];
        // console.log('nextWord.originalMeanings.length == 1  ',this.currentWord);
      } else {
        let randomInt = this.getRandomInt(0, nextWord.originalMeanings.length);
        if (randomInt > 0) randomInt--;
        else if (randomInt < 0) randomInt = 0;
        this.currentWord.meanSelf = nextWord.originalMeanings[randomInt];
        // console.log('nextWord.originalMeanings.length >= 1  ',this.currentWord);
      }
      this.currentWord.meanLocal = nextWord.translatedMeanings;
      this.currentWord.wordId = nextWord.wordId;
      // this.currentWord.bookId=nextWord.bookId
      if (this.currentWord.meanSelf.meaning.length == 1) {
        this.currentWord.explain = this.currentWord.meanSelf.meaning[0].explain;
      } else {
        let nextIndex = this.getRandomInt(
          0,
          this.currentWord.meanSelf.meaning.length
        );
        if (nextIndex < 0) nextIndex = 0;
        else if (nextIndex > 0) nextIndex--;
        this.currentWord.explain =
          this.currentWord.meanSelf.meaning[nextIndex].explain;
      }
      if (nextWord.translatedMeanings != null && nextWord.translatedMeanings.length >= 1) {
        let nextMeanLocal
        if (nextWord.translatedMeanings.length == 1) nextMeanLocal = nextWord.translatedMeanings[0]
        else {
          let nextIndex = this.getRandomInt(0, nextWord.translatedMeanings.length)
          if (nextIndex < 0) nextIndex = 0;
          else if (nextIndex > 0) nextIndex--;
          nextMeanLocal = nextWord.translatedMeanings[nextIndex]
        }
        this.currentWord.meanLocalExplain = nextMeanLocal.meaning
        this.currentWord.meanLocalType = nextMeanLocal.type
      }
      if (this.currentWord.meanSelf.symbol == null || this.currentWord.meanSelf.symbol == "") {
        if (nextWord.pronunciation.length == 1) {
          this.currentWord.symbol = nextWord.pronunciation[0].symbol;
          this.currentWord.symbolResource = nextWord.pronunciation[0].resource;
          this.currentWord.region = nextWord.pronunciation[0].region;
        } else if (nextWord.pronunciation.length > 1) {
          let pronunciation = nextWord.pronunciation[this.getRandomInt(0, nextWord.pronunciation.length - 1)];
          this.currentWord.symbol = pronunciation.symbol;
          this.currentWord.symbolResource = pronunciation.resource;
          this.currentWord.region = pronunciation.region;
        }
      } else {
        this.currentWord.symbol = this.currentWord.meanSelf.symbol;
        if (nextWord.pronunciation != null && nextWord.pronunciation.length > 0) {
          let pronunciationList = nextWord.pronunciation;
          for (let i = 0; i < pronunciationList.length; i++) {
            let pronunciation = pronunciationList[i];
            if (pronunciation.symbol == this.currentWord.symbol) {
              this.currentWord.symbolResource = pronunciation.resource;
              this.currentWord.region = pronunciation.region;
              break;
            }
          }
        }
      }
      this.getVoiceResource(this.config.autoPlayVoice ? this.currentWord.explain : null, (url) => {
        this.voiceInit++;
        this.currentWord.explainResource = url;
      });
      if (this.currentWord.symbol != null || this.currentWord.symbol != "") {
        if (this.currentWord.symbolResource == null || this.currentWord.symbolResource == "") {
          this.voiceInit++;
          // this.getVoiceResource(this.currentWord.symbol, (url) => {
          //   this.currentWord.symbolResource = url;
          //   this.voiceInit++;
          // });
        } else this.voiceInit++;
      }
      //   console.log(this.currentWord)
      this.voiceLoading = true;
      this.getVoiceTimeout = setTimeout(() => {
        if (this.voiceInit != 2) {
          this.snackbar = true;
          this.text = "获取音频数据失败";
        }
        this.voiceInit = 0;
        this.voiceLoading = false;
        clearTimeout(this.getVoiceTimeout);
      }, 5000);
      this.myAnswer = undefined;
      this.myAnswerOfMean = undefined;
      if (this.$refs.practiceFrame != null) this.$refs.practiceFrame.restoreVKeyboardInput()
      this.retry = false;
      this.replyOneColor = 'initial'
      this.replyTwoColor = 'initial'
    },
    cancelVKBoardInput() {
      if (this.$refs.practiceFrame != null) {
        if(this.config.isVibrate)this.myAnswer = null
        navigator.vibrate(30);
        this.$refs.practiceFrame.restoreVKeyboardInput()
      }
    },
    getPracticeConfit() {
      queryUserPracticeConfig({
        bookId: this.$route.params.bookId,
        practiceModel: "listen",
      }).then((resp) => {
        if (resp.data != null) this.setPracticeConfit(resp.data.configJsonText);
        else this.setPracticeConfit("");
      });
    },
    setPracticeConfit(choosePracticeStorege) {
      //let choosePracticeStorege = localStorage.getItem('practiceConfig-choose')
      let parseResult = true;
      if (choosePracticeStorege != null) {
        try {
          this.config = JSON.parse(choosePracticeStorege);
        } catch (error) {
          console.error("加载配置失败：", error);
          parseResult = false;
        }
      }
      if (!parseResult || choosePracticeStorege == null) {
        this.config = {
          showAutoPlay: true,
          showAutoCover: true,
          autoPlay: false,
          autoCover: true,
          showAutoPlayVoice: true,
          autoPlayVoice: false,
          showReplyTypeSwitch: false,
          replyTypeSwitch: false,
          showReplyWordSwitch: true,
          replyWordSwitch: true,
          showReplyMeanSwitch: true,
          replyMeanSwitch: false,
          showQuickKeySwitch: true,
          quickKeySwitch: true,
          showKeyboardSwitch: true,
          showKeyboard: false,
          showTitleLocalSwitch: true,
          titleLocalSwitch: true,
          showAutoPlayResponded: true,
          autoPlayResponded: false,
          showSensorSwitch: true,
          sensorSwitch: false,
          showPalmSwitch: true,
          palmSwitch: false,
          showVibrateSwitch:true,
          isVibrate:false
        };
      }
      if (!this.config.autoCover) this.coverConfig = { word: false, explain: false }
      setTimeout(() => {
        this.$refs.practiceFrame.setPracticeConfig(this.config);
      }, 500);
    },
    setPracticeCallback(practice) {
      this.trans(practice.word);
      this.wordTemp = practice.word;
      if (this.audio != null) {
        this.audio.pause();
        this.audio = null;
      }
      this.playing = false;
      if (this.config.replyWordSwitch && this.config.replyMeanSwitch)
        this.$refs.wordField.focus();
    },
    getRandomInt(min, max) {
      min = Math.ceil(min);
      max = Math.floor(max);
      return Math.floor(Math.random() * (max - min + 1)) + min; //含最大值，含最小值
    },
    getVoiceResource(text, callback) {
      ttsVoice({ text: text }).then((resp) => {
        callback(resp.data);
      });
    },
    quickKeyListener(keyCode) {
      // console.log('反馈：',keyCode);
      if (keyCode != 188) return
      if (document.activeElement == document.getElementById('replyWordSwitch'))
        this.$refs.meanField.focus()
      else
        this.$refs.wordField.focus();
    },
    VKeyboardInputListener(input) {
      this.myAnswer = input
      // navigator.vibrate(30);
    },
    VKeyboardPressListener(VKeyCode) {
      if (VKeyCode == '{ent}') this.reply()
    },
    sensorListener(data) {
      // console.log(data);
      if (data.gamma > 0) console.log('右边');
      if (data.gamma < 0) console.log('左边');
    },
    autoPalyOnceListener() {
      if (this.currentWord.explainResource == null) return;
      this.audio = new Audio(this.currentWord.explainResource);
      this.audio.play();
      this.playing = true;
      this.audio.onended = () => {
        this.playing = false;
      };
    }
  },
  watch: {
    voiceInit() {
      if (this.voiceInit == 2) {
        this.voiceLoading = false;
        if (this.config.autoPlayVoice) {
          // this.play();
        }
      }
    },
    'config.showKeyboardSwitch'(newValue) {
      if (this.$refs.practiceFrame == null) return
      if (!newValue) this.$refs.practiceFrame.restoreVKeyboardInput();
      else this.$refs.practiceFrame.setVKeyboardInput(this.myAnswer)
    },
    'config.showKeyboard'(newValue) {
      if (this.$refs.practiceFrame == null) return
      if (!newValue) this.$refs.practiceFrame.restoreVKeyboardInput();
      else this.$refs.practiceFrame.setVKeyboardInput(this.myAnswer)
    }
  },
};
</script>

<style scoped>
.centerDiv {
  width: 100%;
  text-align: center;
  margin: auto;
}

.detail_bottom {
  margin-top: 50px;
}

.detail_bottom::after {
  content: "";
  display: block;
}

.detail_bottom span {
  font-size: 18px;
}

.div_blur {
  filter: blur(5px);
}

.flat-input {
  min-height: 52px;
  text-align: center;
  font-weight: bold;
  font-size: 30px;
  overflow: hidden;
  line-height: 50px;
  color: black;
  border: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
}

.text-limit {
  -webkit-line-clamp: 3;
  line-clamp: 3;
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  text-overflow: ellipsis;
  white-space: normal;
}
</style>